package com.utc.cards.games.damedepique;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import android.app.Fragment;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.utc.cards.R;
import com.utc.cards.common.view.CardView;
import com.utc.cards.common.view.RectView;
import com.utc.cards.model.HostModel;
import com.utc.cards.model.game.Fold;
import com.utc.cards.model.player.IPlayer;
import com.utc.cards.utils.Utils;

public class FragmentDameDePiqueTableGameActivity extends Fragment implements OnTouchListener
{

    private Point _displayDimentions = new Point();
    private View _rootView;

    private RelativeLayout _foldCardsLayout;
    private TableLayout _tableLayout;

    private List<LinearLayout> _displayedCards = new ArrayList<LinearLayout>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        _rootView = inflater.inflate(R.layout.fragment_activity_dame_de_pique_table_game, container, false);

        _rootView.setOnTouchListener(this);

        _displayDimentions = Utils.getDisplayWindowsDimention(this.getActivity());

        _foldCardsLayout = (RelativeLayout) _rootView.findViewById(R.id.foldCardsLayout);
        _tableLayout = (TableLayout) _rootView.findViewById(R.id.scoreTable);

        _foldCardsLayout.removeAllViews();
        _tableLayout.removeAllViews();

        // Pour test
        // updateBoard(HostModel.Instance().getCurrentFold());
        // updateScore(true, HostModel.Instance().getScores().getLastPartyScore());
        // Fin pour test

        return _rootView;
    }

    public void updateBoard(Fold fold)
    {
        if (_foldCardsLayout != null)
        {
            _foldCardsLayout.removeAllViews();
            _displayedCards.clear();

            int cpt = 0;

            CardView.CARD_WIDTH = (int) (_displayDimentions.x * 0.15);

            for (String k : fold.getFoldCards().keySet())
            {
                IPlayer p = HostModel.Instance().getGame().getPlayerByName(k);

                if (p != null)
                {

                    LinearLayout layout = new LinearLayout(this.getActivity());

                    CardView cv = new CardView(fold.getFoldCards().get(k).get(0), _foldCardsLayout.getContext());

                    layout.addView(cv);
                    layout.setPadding(0, 8, 0, 0);

                    GradientDrawable gb = new GradientDrawable();
                    gb.setCornerRadius(10f);
                    gb.setStroke(10, p.getDisplayColor());
                    gb.setAlpha(200);

                    layout.setBackgroundDrawable(gb);

                    int rot = cpt * 90;

                    layout.setRotation(rot);

                    Point pt = getCenterDistance(cpt);

                    layout.setTranslationX(pt.x);
                    layout.setTranslationY(pt.y);

                    _foldCardsLayout.addView(layout);
                    _displayedCards.add(layout);
                }

                cpt++;

                if (cpt == 4)
                    break;
            }
        }
    }

    public void updateScore(boolean displayScore, Map<String, Integer> scoreMap)
    {
        if (_tableLayout != null)
        {
            if (displayScore)
            {
                _tableLayout.setVisibility(View.VISIBLE);
                _tableLayout.removeAllViews();

                if (scoreMap != null)
                {
                    ArrayList<Pair<String, Integer>> scoreList = new ArrayList<Pair<String, Integer>>();

                    for (String p : scoreMap.keySet())
                    {
                        scoreList.add(new Pair<String, Integer>(p, scoreMap.get(p)));
                    }

                    // On tri la liste afin que le joueur ayant le meilleur score
                    // soit
                    // en
                    // tête de liste
                    orderScoreList(scoreList);

                    drawScoreTable(scoreList);
                }
            }
            else
            {
                _tableLayout.setVisibility(View.INVISIBLE);
            }
        }
    }

    public void launchWinnerAnimation(IPlayer winner)
    {
        System.out.println("Fin de tour, déclaration du vainqueur");

        animateCards(getPlayerOrientation(winner));
    }

    public void displayGameWinner(IPlayer winner)
    {
        if (_foldCardsLayout != null)
        {
            _foldCardsLayout.removeAllViews();

            TextView tv = new TextView(this.getActivity());
            tv.setText("Le vainqueur est " + winner.getName() + " !");
            tv.setTextSize(30);
            tv.setTextColor(Color.WHITE);
            tv.setTypeface(null, Typeface.BOLD);
            tv.setGravity(Gravity.CENTER);

            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            lp.addRule(RelativeLayout.CENTER_IN_PARENT);

            tv.setLayoutParams(lp);

            _foldCardsLayout.addView(tv);

            LinearLayout layout = new LinearLayout(_foldCardsLayout.getContext());
            layout.setGravity(Gravity.BOTTOM | Gravity.CENTER);

            Button bt = new Button(this.getActivity());
            bt.setText("Revanche");
            bt.setPadding(10, 10, 10, 10);
            bt.setTextSize(25);
            bt.setTypeface(null, Typeface.BOLD);
            bt.setTextColor(Color.WHITE);
            bt.setBackgroundResource(R.drawable.red_button);

            lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            lp.bottomMargin = 20;

            layout.addView(bt);

            layout.setLayoutParams(lp);

            _foldCardsLayout.addView(layout);
        }
    }

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1)
    {
        System.out.println("Retourner la dernière carte jouée");

        return false;
    }

    private void orderScoreList(ArrayList<Pair<String, Integer>> scoreList)
    {
        boolean changementHappened = true;

        while (changementHappened)
        {
            changementHappened = false;

            for (int i = 0; i < scoreList.size() - 1; i++)
            {
                if (scoreList.get(i).second > scoreList.get(i + 1).second)
                {
                    Pair<String, Integer> tmp = scoreList.get(i + 1);
                    scoreList.remove(i + 1);
                    scoreList.add(i + 1, scoreList.get(i));

                    scoreList.remove(i);
                    scoreList.add(i, tmp);

                    changementHappened = true;
                }
            }
        }
    }

    private void drawScoreTable(List<Pair<String, Integer>> scores)
    {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) _tableLayout.getLayoutParams();
        lp.width = (int) (_displayDimentions.x * 0.18);
        _tableLayout.setLayoutParams(lp);

        int textSize = (int) (_displayDimentions.x * 0.011);

        TableRow row;
        TextView t1, t2;
        RectView rv;

        for (Pair<String, Integer> s : scores)
        {
            IPlayer p = HostModel.Instance().getGame().getPlayerByName(s.first);

            if (p != null)
            {
                row = new TableRow(this.getActivity());

                rv = new RectView(0, (int) (textSize * 0.75), 15, textSize, p.getDisplayColor(), false, _rootView.getContext());

                rv.setPadding(0, 0, 0, 0);

                t1 = new TextView(this.getActivity());
                t2 = new TextView(this.getActivity());

                t1.setPadding(10, 0, 0, 0);

                t1.setText(s.first);
                t2.setText("" + s.second);

                t1.setTextSize(textSize);
                t2.setTextSize(textSize);

                t1.setTypeface(null, Typeface.ITALIC);
                t2.setTypeface(null, Typeface.BOLD);

                row.addView(rv);
                row.addView(t1);
                row.addView(t2);

                _tableLayout.addView(row, new TableLayout.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
            }
        }
    }

    private Point getCenterDistance(int pos)
    {
        int d = (int) (CardView.CARD_WIDTH * 0.75);
        Point p = new Point();
        switch (pos)
        {
        case 0:
            p = new Point(0, -d);
            break;
        case 1:
            p = new Point((int) (d * 1.7), 0);
            break;
        case 2:
            p = new Point(0, d);
            break;
        case 3:
            p = new Point((int) (-d * 1.7), 0);
            break;
        default:
            break;
        }

        return p;
    }

    private void animateCards(int playerOrientation)
    {
        System.out.println("translateCards: " + playerOrientation);

        for (LinearLayout card : _displayedCards)
        {
            int cardIndex = _displayedCards.indexOf(card);
            int rot = (playerOrientation * 90 + cardIndex * 90) % 360;

            RotateAnimation r_anim = new RotateAnimation(0, rot, Animation.ABSOLUTE, card.getPivotX(), Animation.ABSOLUTE, card.getPivotY());
            r_anim.setDuration(500);
            r_anim.setFillAfter(true);
            r_anim.setFillEnabled(true);

            r_anim.setAnimationListener(new MyAnimationListener(card, playerOrientation, cardIndex));

            card.startAnimation(r_anim);
        }
    }

    private class MyAnimationListener implements AnimationListener
    {
        private View _view;
        private int _playerOrientation;
        private int _cardIndex;

        public MyAnimationListener(View view, int playerOrientation, int cardIndex)
        {
            _view = view;
            _playerOrientation = playerOrientation;
            _cardIndex = cardIndex;
        }

        @Override
        public void onAnimationEnd(Animation animation)
        {
            if (animation instanceof RotateAnimation)
            {
                int rot = _playerOrientation * 90;

                System.out.println("Rotation(" + _cardIndex + "): " + rot);
                _view.setRotation(rot);

                if (_playerOrientation % 2 == 0)
                {
                    _view.setTranslationX(0);
                }
                else
                {
                    _view.setTranslationY(0);
                }

                Point p = getTranslationPoint(_playerOrientation);

                System.out.println("TranslationPoint(" + _playerOrientation + ") : " + p.x + " - " + p.y);

                TranslateAnimation t_anim = new TranslateAnimation(0, p.x, 0, p.y);
                t_anim.setDuration(1200);
                t_anim.setFillAfter(true);

                t_anim.setAnimationListener(new MyAnimationListener(_view, _playerOrientation, _cardIndex));

                _view.startAnimation(t_anim);

            }
            else if (animation instanceof TranslateAnimation)
            {
                _foldCardsLayout.removeView(_view);
                _displayedCards.remove(_view);
            }
        }

        @Override
        public void onAnimationRepeat(Animation animation)
        {
        }

        @Override
        public void onAnimationStart(Animation animation)
        {
        }

    }

    private int getPlayerOrientation(IPlayer p)
    {
        return HostModel.Instance().getGame().getPlayerNames().indexOf(p.getName()) % 4;
    }

    private Point getTranslationPoint(int dir)
    {
        int dx = (int) (_displayDimentions.x);
        int dy = (int) (_displayDimentions.y);
        Point p = new Point();

        switch (dir)
        {
        case 0:
            p = new Point(0, -dy);
            break;
        case 1:
            p = new Point(dx, 0);
            break;
        case 2:
            p = new Point(0, dy);
            break;
        case 3:
            p = new Point(-dx, 0);
            break;
        default:
            break;
        }

        return p;
    }

}
